<?php
/**
 * Dirox Framework
 * Copyright (C) 2005 - 2007 Dirox / Synexser
 *
 * All rights reserved.
 */

require_once APPLICATION_DIR . '/library/external/PEAR/Pager.php';


class DBPager
{
	var $db_object = null;
	var $pg_object = null;
    var $extraVars = array();
    var $FirstLink;
    var $LastLink;
	var $BackLink;
	var $NextLink;
	var $PageListLink;
	var $current_page = 0;
	var $ajax;
	var $functionName;
	var $options;
	var $attrib = array();
	var $attribLink;
	var $isQuery = false;

	function DBPager(&$db_object, $extraVars = array(), $isGroup = false, $itemPerPage=PAGING_DEFAULT_ITEM_PER_PAGE, &$query='')
	{
		$this->db_object 		= $db_object;
        $this->extraVars 		= $extraVars;
        $this->group = $isGroup;
        
        if ($query)
        {
        	$this->isQuery = true;
        	$this->implementPagingQuery($itemPerPage, $query);
        }
        else
        {
        	$this->implementPaging($itemPerPage);
        }
	}

	function getNavPaging()
	{
		$this->SetAttribute();
		$this->SetFirstLink();
		$this->SetLastLink();
		$this->SetBackLink();
		$this->SetNextLink();
		$this->SetPageListLink();
	}

	function addAttribute($attrib)
	{
		$this->attrib = array_merge($this->attrib,$attrib);
	}

	function SetAttribute()
	{
		$this->attribLink = "";
		if (count($this->attrib))
		{
			
			foreach ($this->attrib as $name => $value)
			{
				$this->attribLink .= " ".$name."=".$value;
			}
		}
	}

	function implementPagingQuery($itemPerPage, &$query)
	{
		$object_page = 'page';
		$this->current_page = Request::getIntNumber($object_page);
		if( $this->current_page == 0 ) $this->current_page = 1;

		$numrec = 0;
		
        if ($this->group)
       	{
       		
       	}
       	else
       	{
       		$sql = "SELECT COUNT(*) NUMREC FROM ( " . $query . " ) TBLTMP";
       		$this->db_object->query($sql);
       		$numrec = 0;
       		if ($this->db_object->fetch())
       		{
       			$numrec = $this->db_object->NUMREC;
       		}
       	}

       	$this->options = array(
			'totalItems' 			=> $numrec,
			'perPage' 	 			=> $itemPerPage,
			'delta'		 			=> PAGING_DEFAULT_PAGE_DELTA,
			'httpMethod' 			=> 'GET',
			'currentPage' 			=> $this->current_page,
			'linkClass'				=> PAGING_CSS_LINK_CLASS,
			'urlVar' 				=> $object_page,
			'altPrev' 				=> PAGING_PREV,
			'altNext' 				=> PAGING_NEXT,
			'separator' 			=> PAGING_SEPARATOR,
            'extraVars' 			=> $this->extraVars,
			'curPageLinkClassName' 	=> PAGING_CSS_CURRENT_PAGE,
			'path' 					=> ""
		);

		$this->pg_object = Pager::factory($this->options);

        if ($this->current_page > $this->pg_object->numPages() && $this->current_page != 1)
        {
        	$this->current_page = $this->pg_object->numPages();
        }

		// merge all url args and request args into 1
		self::mergeArgs();

		if ($this->group)
        {
        	
        }
        else
       	{
       		$query .= " LIMIT " . (($this->current_page-1) * $itemPerPage) . ", $itemPerPage ";
       	}
	}
	
	function implementPaging($itemPerPage)
	{
		$object_page = 'page';
		$this->current_page = Request::getIntNumber($object_page);
		if( $this->current_page == 0 ) $this->current_page = 1;

		$numrec = 0;
		
        if ($this->group)
       	{
       		//Fix grouping pager
	    	$clony = clone $this->db_object;
	    	$keys = $clony->keys();
	    	$clony->selectAdd('count(*)');
	    	$clony->groupBy();
			$clony->groupBy($clony->__table . '.' . $keys[0]);
			$clony->find();
			$numrec = $clony->N;
       	}
       	else
       	{
       		$clony = clone $this->db_object;
       		$clony->find();
       		$numrec = $clony->N;
       	}

       	$this->options = array(
			'totalItems' 			=> $numrec,
			'perPage' 	 			=> $itemPerPage,
			'delta'		 			=> PAGING_DEFAULT_PAGE_DELTA,
			'httpMethod' 			=> 'GET',
			'currentPage' 			=> $this->current_page,
			'linkClass'				=> PAGING_CSS_LINK_CLASS,
			'urlVar' 				=> $object_page,
			'altPrev' 				=> PAGING_PREV,
			'altNext' 				=> PAGING_NEXT,
			'separator' 			=> PAGING_SEPARATOR,
            'extraVars' 			=> $this->extraVars,
			'curPageLinkClassName' 	=> PAGING_CSS_CURRENT_PAGE,
			'path' 					=> ""
		);

		$this->pg_object = Pager::factory($this->options);

        if ($this->current_page > $this->pg_object->numPages() && $this->current_page != 1)
        {
        	$this->current_page = $this->pg_object->numPages();
        }

		// merge all url args and request args into 1
		self::mergeArgs();

		if ($this->group)
        {
        	$clony->limit(($this->current_page-1) * $itemPerPage, $itemPerPage);
			$clony->find();
			$ids = "";
			while ($clony->fetch())
			{
				eval('$ids .= "," . $clony->' . $keys[0] . ";");
			}
			$ids = trim($ids, ",");
			if ($ids!=""){
				 $ids = "," . $ids;
			}
			$this->db_object->whereAdd($this->db_object->__table . '.' . $keys[0] . ' IN (-1' . $ids . ')');
        }
        else
       	{
       		$this->db_object->limit(($this->current_page-1) * $itemPerPage, $itemPerPage);
       	}

	}

	function SetFirstLink()
	{
		$objUrl = new DRX_UrlParser();
		$root_path = $objUrl->GetRootPath();
		$link = $objUrl->GetModRewriteURL("page")."page=1";
		$range = $this->pg_object->getPageRangeByPageId();
		if ($range[0] > 1)
			$this->FirstLink = "<a class='". PAGING_CSS_LINK_CLASS ."' href='".$root_path.$link."'".$ajax_function.">1</a>... ";
		else
			$this->FirstLink = "";
	}

	function SetLastLink()
	{
		$objUrl = new DRX_UrlParser();
		$root_path = $objUrl->GetRootPath();

		$link = $objUrl->GetModRewriteURL("page")."page=".$this->pg_object->numPages();

		$range = $this->pg_object->getPageRangeByPageId();

		if ($range[1] < $this->pg_object->numPages())
			$this->LastLink = "... <a class='". PAGING_CSS_LINK_CLASS ."' href='".$root_path.$link."'".$ajax_function.">".$this->pg_object->numPages()."</a>".PAGING_SEPARATOR;
		else
			$this->LastLink = "";
	}

	function SetBackLink()
	{
		$objUrl = new DRX_UrlParser();
		$root_path = $objUrl->GetRootPath();

		$link = $objUrl->GetModRewriteURL("page")."page=".($this->current_page-1);
		if($this->pg_object->_getBackLink()!="")
		{
			if($this->ajax === true) {
        		$ajax_function   = ' onclick="return '.$this->functionName.'('.($this->current_page-1).')"';
       		}
       		else $ajax_function = "";

			$this->BackLink = "<a class='". PAGING_CSS_LINK_CLASS ."' href='".$root_path.$link."'".$ajax_function.">".PAGING_PREV."</a>".PAGING_SEPARATOR;
		}

	}

	function SetNextLink()
	{
		$objUrl = new DRX_UrlParser();
		$root_path = $objUrl->GetRootPath();
		$link = $objUrl->GetModRewriteURL("page")."page=".($this->current_page+1);
		if($this->pg_object->_getNextLink()!="")
		{
			if($this->ajax === true) {
        		$ajax_function   = ' onclick="return '.$this->functionName.'('. ($this->current_page+1) .')"';
       		}
       		else $ajax_function = "";

			$this->NextLink = "<a class='". PAGING_CSS_LINK_CLASS ."' href='".$root_path.$link."'".$ajax_function.">".PAGING_NEXT."</a>";

		}
	}

	function SetPageListLink()
	{
		$objUrl = new DRX_UrlParser();
		$root_path = $objUrl->GetRootPath();
		$link = $objUrl->GetModRewriteURL("page");

		$total_page = $this->pg_object->numPages();
		//echo $link;
		if($total_page>0)
		{
			list($min, $max) = $this->pg_object->getPageRangeByPageId();
			for($i = $min; $i <= $max; $i++)
			{
				$ajax_function = "";
				if($this->ajax === true) {
        			$ajax_function   = ' onclick="return '.$this->functionName.'('.$i.')"';
       			}
				if($i==$this->current_page)
					$this->PageListLink.= "<span class='".PAGING_CSS_CURRENT_PAGE."'>".$i."</span>".PAGING_SEPARATOR;
				else
					$this->PageListLink.= "<a ".$this->attribLink." href='".$root_path.$link."page={$i}' class='".PAGING_CSS_LINK_CLASS."'".$ajax_function.">".$i."</a>".PAGING_SEPARATOR;
			}
		}

		$this->PageListLink = trim($this->PageListLink,"-&nbsp;");
	}

	function setFunctionForAjaxCall($functionName)
	{
		$this->ajax = true;
		$this->functionName = $functionName;
	}

	function disableAJAX()
	{
		$this->ajax = false;
	}

	function display()
	{
		if ($this->options['perPage'] >= $this->options['totalItems']) 
		{
			return;
		}
		
		$this->getNavPaging();
		
		echo $this->BackLink.$this->FirstLink.$this->PageListLink.$this->LastLink.$this->NextLink;
	}

	function returnHTML()
	{
		if ($this->options['perPage'] >= $this->options['totalItems']) {
			return "";
		}

		$this->getNavPaging();
		return $this->BackLink.$this->PageListLink.$this->NextLink;
	}

	function returnRange()
	{
		if ($this->options['perPage'] >= $this->options['totalItems']) {
			return "";
		}

		$max = $this->current_page * $this->options['perPage'];
		$min = $max - $this->options['perPage'] + 1;
		$max = ($max > $this->options['totalItems']) ? $this->options['totalItems'] : $max;
		if ($min == $max) {
			return "$min of ".$this->options['totalItems'];
		} else {
			return "$min - $max of ".$this->options['totalItems'];
		}
	}
	
	// merge url arguments and request arguments into 1
	private function mergeArgs()
	{
        if (sizeof($this->extraVars) > 0)
        {
        	// encode and set to GlobalVar (for using in urlParser's process)
        	urlencode_array($this->extraVars);
        	$postArgs = $this->extraVars;
        	
			// get back "url args"
			$args 	= DRX::load("args");
			
			if (!is_null($postArgs) && $postArgs != "")
			{
				// merge with args (from url) if need
				if ($args != "")
				{
					$arrExps = array_reverse(explode("&",$args));
					$arrUrlArgs = array();
					for($i=0; $i<sizeof($arrExps); $i++) 
					{
						list($ks, $vs) = explode("=", $arrExps[$i]);
						$arrUrlArgs[$ks] = $vs;
					}
					$postArgs = array_merge($arrUrlArgs, $postArgs);
				}
	
				$tmpStr = "";
				foreach($postArgs as $argsKey => $myVal)
				{
					
					if ($tmpStr != "")
					{
						$tmpStr .= "&";
					}
					$tmpStr .= $argsKey . "=" . $myVal;
				}
				
				// new string of arguments
				$args = $tmpStr;
			}

			DRX::register("args", $args);
        }
	}
}
